﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.Validation.Interfaces;

namespace Kiiro.Validation.Validators.Entities
{
    public class ProjectValidator : BaseEntityValidator, IValidator<Project>
    {
        private readonly List<ValidationMessage> validationErrors = new List<ValidationMessage> ( );

        #region  IValidator<Project> Members
        public List<ValidationMessage> Validate ( Project entityToValidate )
        {
            // If the entity is marked as deleted, don't do any validation, just return.
            if ( entityToValidate.EditType != EditType.Deleted )
            {
                ValidationMessage message = null;

                #region Required Fields Checks

                if ( entityToValidate.EditType == EditType.Created )
                {
                    message = IsRequired ( entityToValidate.ServerRelativeWebUrl, "Web Url" );

                    if ( message != null )
                    {
                        entityToValidate.ServerRelativeWebUrlMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                message = IsRequired ( entityToValidate.Title, "Title" );

                if ( message != null )
                {
                    entityToValidate.TitleMessage.Add ( message );
                    validationErrors.Add ( message );
                }

                message = IsRequired ( entityToValidate.ProjectStatus.ToString ( ), "Project Status" );

                if ( message != null )
                {
                    entityToValidate.ProjectStatusMessage.Add ( message );
                    validationErrors.Add ( message );
                }                             

                #endregion

                #region Comparison Checks

                if ( !string.IsNullOrEmpty ( entityToValidate.Title ) )
                {
                    message = CheckMaximumLength ( 200, entityToValidate.Title, "Title" );

                    if ( message != null )
                    {
                        entityToValidate.TitleMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.Title, "Title" );

                    if ( message != null )
                    {
                        entityToValidate.TitleMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.Description ) )
                {
                    message = CheckMaximumLength ( 1000, entityToValidate.Description, "Description" );

                    if ( message != null )
                    {
                        entityToValidate.DescriptionMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.Description, "Description" );

                    if ( message != null )
                    {
                        entityToValidate.DescriptionMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.SummaryNote ) )
                {
                    message = CheckMaximumLength ( 1000, entityToValidate.SummaryNote, "Summary Note" );

                    if ( message != null )
                    {
                        entityToValidate.SummaryNoteMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.SummaryNote, "Summary Note" );

                    if ( message != null )
                    {
                        entityToValidate.SummaryNoteMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                message = NotNegative ( entityToValidate.TotalWork, "Total Work" );

                if ( message != null )
                {
                    entityToValidate.TotalWorkMessage.Add ( message );
                    validationErrors.Add ( message );
                }

                message = NotNegative ( entityToValidate.ActualWork, "Actual Work" );

                if ( message != null )
                {
                    entityToValidate.ActualWorkMessage.Add ( message );
                    validationErrors.Add ( message );
                }

                message = NotNegative ( entityToValidate.ProjectedWork, "Projected Work" );

                if ( message != null )
                {
                    entityToValidate.ProjectedWorkMessage.Add ( message );
                    validationErrors.Add ( message );
                }

                if ( entityToValidate.StartDate != DateTime.MinValue && entityToValidate.EndDate != DateTime.MinValue )
                {
                    message = NotGreaterThan ( entityToValidate.StartDate, entityToValidate.EndDate, "Start Date", "End Date" );
                    if ( message != null )
                    {
                        entityToValidate.StartDateMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( entityToValidate.EditType == EditType.Created && !string.IsNullOrEmpty ( entityToValidate.ServerRelativeWebUrl ) )
                {
                    message = CheckMaximumLength ( 128, entityToValidate.ServerRelativeWebUrl, "Web Url" );

                    if ( message != null )
                    {
                        entityToValidate.ServerRelativeWebUrlMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                    //else
                    {
                        message = HasSpecialCharactersForSiteUrlInText ( entityToValidate, "web url" );

                        if (message != null)
                        {
                            entityToValidate.ServerRelativeWebUrlMessage.Add(message);
                            validationErrors.Add(message);
                        }
                        else
                        {
                            message = DoesWebExist(entityToValidate.ServerRelativeWebUrl, entityToValidate.SiteCollectionId, entityToValidate.ServerRelativeUrl);

                            if (message != null)
                            {
                                entityToValidate.ServerRelativeWebUrlMessage.Add(message);
                                validationErrors.Add(message);
                            }
                        }
                    }
                }

                if ( entityToValidate.ProjectPlanBytes != null && entityToValidate.ProjectPlanFileUrl != null )
                {

                    message = VerifyFileExtension ( entityToValidate.ProjectPlanFileUrl );

                    if ( message != null )
                    {
                        entityToValidate.ProjectPlanBytesMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = VerifyFileSize ( entityToValidate.ProjectPlanBytes );

                    if ( message != null )
                    {
                        entityToValidate.ProjectPlanBytesMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( entityToValidate.IsWPSandboxActivated )
                {
                    message = IsRequired ( entityToValidate.WPSandboxNavText, "Tab Text" );

                    if ( message != null )
                    {
                        entityToValidate.WPSandboxNavTextMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    if ( !string.IsNullOrEmpty ( entityToValidate.WPSandboxNavText ) )
                    {
                        message = CheckMaximumLength ( 30, entityToValidate.WPSandboxNavText, "Tab Text" );

                        if ( message != null )
                        {
                            entityToValidate.WPSandboxNavTextMessage.Add ( message );
                            validationErrors.Add ( message );
                        }

                        message = HasScriptingTagsInText ( entityToValidate.WPSandboxNavText, "Tab Text" );

                        if ( message != null )
                        {
                            entityToValidate.WPSandboxNavTextMessage.Add ( message );
                            validationErrors.Add ( message );
                        }
                    }
                }

                #endregion

            }

            return validationErrors;
        }

        #endregion

        private ValidationMessage VerifyFileExtension ( string value )
        {
            ValidationMessage message = null;
            if ( !VerifyProjectFileExtension ( value ) )
            {
                message = new ValidationMessage ( ValidationSeverity.Validation, "Invalid file extension. File must be a .MPP file." );
            }
            return message;
        }

        private bool VerifyProjectFileExtension ( string fileName )
        {
            string extension = System.IO.Path.GetExtension ( fileName );
            return ( extension.ToUpper ( ) == ".MPP" );
        }

        private ValidationMessage VerifyFileSize ( byte [ ] value )
        {
            ValidationMessage message = null;
            if ( !VerifyProjectFileSize ( value ) )
            {
                message = new ValidationMessage ( ValidationSeverity.Validation, "File size has to be less than 10 MB." );
            }
            return message;
        }

        private bool VerifyProjectFileSize ( byte [ ] file )
        {
            MemoryStream memoryStream = new MemoryStream ( file );
            int fileSize = memoryStream.Capacity;
            // Allow only files less than 10,100,000 bytes (approximately 10 MB) to be uploaded.
            return ( fileSize < 10100000 );
        }

        private ValidationMessage DoesWebExist ( string webUrl, Guid siteCollectionId, string serverRelativeUrl )
        {
            ValidationMessage message = null;

            using ( SPWeb portalWeb = SPHelpers.GetPortalWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                using ( SPWeb web = portalWeb.Site.OpenWeb ( SPHelpers.GetServerRelativeUrl ( portalWeb ) + "/" + webUrl ) )
                {
                    if ( web.Exists )
                    {
                        message = new ValidationMessage ( ValidationSeverity.Validation, "The Web site address " + webUrl + " is already in use." );
                    }
                }
            }

            return message;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Validation/Validators/Entities/ProjectValidator.cs $
 * 
 * 5     10/26/09 10:45a Adamw
 * Case 332
 * 
 * 4     17/08/09 10:45a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/